home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / lib / posix / getcwd.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  3KB  |  117 lines

  1. /*  getcwd - get current working directory    Author: Terrence W. Holm */
  2.  
  3. /* Directly derived from Adri Koppes' pwd(1).
  4.  * Modified by Andy Tanenbaum for POSIX (29 Oct. 1989)
  5.  */
  6.  
  7. #include <lib.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <sys/dir.h>
  11. #include <unistd.h>
  12. #include <string.h>
  13.  
  14. #define  DIRECT_SIZE  (sizeof (struct direct))
  15.  
  16. extern char *rindex();
  17.  
  18. char *getcwd(buffer, size)
  19. char *buffer;
  20. int size;
  21. /* Get current working directory. */
  22. {
  23.   int same_device, found, fd;
  24.   char *r, path[PATH_MAX + 1], temp_name[NAME_MAX + 1];
  25.   struct stat current, parent, dir_entry;
  26.   struct direct d;
  27.  
  28.   if (buffer == (char *)NULL || size <= 0) {
  29.     errno = EINVAL;
  30.     return((char *)NULL);
  31.   }
  32.   path[0] = '\0';
  33.  
  34.   /* Get the inode for the current directory  */
  35.   if (stat(".", ¤t) == -1) return((char *)NULL);
  36.   if ((current.st_mode & S_IFMT) != S_IFDIR) return((char *)NULL);
  37.  
  38.   /* Run backwards up the directory tree, grabbing dir names on the way. */
  39.   while (1) {
  40.     same_device = 0;
  41.     found = 0;
  42.  
  43.     /* Get the inode for the parent directory  */
  44.     if (chdir("..") == -1) return((char *)NULL);
  45.     if (stat(".", &parent) == -1) return((char *)NULL);
  46.     if ((parent.st_mode & S_IFMT) != S_IFDIR) return((char *)NULL);
  47.     if (current.st_dev == parent.st_dev) same_device = 1;
  48.  
  49.     /* At the root, "." is the same as ".."  */
  50.     if (same_device && current.st_ino == parent.st_ino) break;
  51.  
  52.     /* Search the parent directory for the current entry  */
  53.     if ((fd = open(".", O_RDONLY)) == -1) return((char *)NULL);
  54.     while (!found && read(fd, (char *)&d, DIRECT_SIZE) == DIRECT_SIZE) {
  55.         if (d.d_ino == 0L) continue;    /* empty slot */
  56.         if (same_device) {
  57.             if (current.st_ino == d.d_ino) found = 1;
  58.         } else {
  59.             temp_name[0] = '\0';
  60.             strncat(temp_name, d.d_name, NAME_MAX);
  61.             if (stat(temp_name, &dir_entry) == -1)continue;
  62.             if (current.st_dev == dir_entry.st_dev &&
  63.                 current.st_ino == dir_entry.st_ino)
  64.                 found = 1;
  65.         }
  66.     }
  67.  
  68.     close(fd);
  69.     if (!found) {
  70.         go_back(path);
  71.         return((char *)NULL);
  72.     }
  73.     if (strlen(path) + NAME_MAX + 1 > PATH_MAX) {
  74.         errno = ERANGE;
  75.         go_back(path);
  76.         return((char *)NULL);
  77.     }
  78.     strcat(path, "/");
  79.     strncat(path, d.d_name, NAME_MAX);
  80.     current.st_dev = parent.st_dev;
  81.     current.st_ino = parent.st_ino;
  82.   }
  83.  
  84.   /* Copy the reversed path name into <buffer>  */
  85.   if (strlen(path) + 1 > size) {
  86.     errno = ERANGE;
  87.     go_back(path);
  88.     return((char *)NULL);
  89.   }
  90.   if (strlen(path) == 0) {
  91.     strcpy(buffer, "/");
  92.     return(buffer);
  93.   }
  94.   *buffer = '\0';
  95.   while ((r = rindex(path, '/')) != (char *)NULL) {
  96.     strcat(buffer, r);
  97.     *r = '\0';
  98.   }
  99.   return(chdir(buffer) ? (char *)NULL : buffer);
  100. }
  101.  
  102. PRIVATE go_back(path)
  103. char *path;
  104. {
  105. /* If getcwd() gets in trouble and can't complete normally, reverse the
  106.  * path built so far and change there so we end up in the directory that
  107.  * we started in.
  108.  */
  109.  
  110.   char *r;
  111.  
  112.   while ((r = rindex(path, '/')) != (char *)NULL) {
  113.     chdir(r+1);
  114.     *r = '\0';
  115.   }
  116. }
  117.